//
// Created by fazhehy on 2024/6/7.
//

#include "protocol.h"

struct Remote remote;

void protocol_init()
{
    remote.transmitBuffer = transmit_buffer;
    remote.receiveBuffer = receive_buffer;
    remote.state = NORMAL;
    remote.id = 0;
    remote.transmitBufferLen = 0;
    remote.medAdcValue1 = 0;
    remote.medAdcValue2 = 0;
    remote.protocolState = 0;
    for (int i = 0; i < 100; ++i) {
//        adc_show();
        remote.medAdcValue1 += adc_value[2];
        remote.medAdcValue2 += adc_value[3];
        HAL_Delay(1);
    }
    remote.medAdcValue1 /= 100;
    remote.medAdcValue2 /= 100;
}

bool protocol_check()
{
    remote.transmitBuffer[0] = 'S';
    remote.transmitBuffer[1] = pageBufferPointer;
    remote.transmitBufferLen = 2;
    uint32_t tick = 0;
    remote.protocolState = 0;
    while (remote.protocolState == 0){
        if (tick >= 100){
            return false;
        }
        if (remote.transmitBufferLen == 0){
            remote.transmitBuffer[0] = 'S';
            remote.transmitBuffer[1] = pageBufferPointer;
            remote.transmitBufferLen = 2;
        }
        HAL_Delay(10);
        tick ++;
    }
    if (remote.protocolType == 'S'){
//        remote.transmitBuffer[0] = 'S';
//        remote.transmitBuffer[1] = pageBufferPointer;
//        remote.transmitBufferLen = 2;
        remote.protocolState = 0;
        if (remote.id == pageBufferPointer){
            return true;
        }
        else{
            return false;
        }
    }
    remote.protocolState = 0;
    return false;
}

void protocol_send_command(uint8_t keyNum, uint16_t adcValue1, uint16_t adcValue2)
{
    if (remote.transmitBufferLen == 0){
        memset(remote.transmitBuffer, 0, 32);
        remote.transmitBuffer[0] = 'C';
        remote.transmitBuffer[1] = remote.id;
        remote.transmitBuffer[2] = keyNum;
        remote.transmitBuffer[3] = (adcValue1 >> 8)&0xff;
        remote.transmitBuffer[4] = (adcValue1)&0xff;
        remote.transmitBuffer[5] = (remote.medAdcValue1 >> 8)&0xff;
        remote.transmitBuffer[6] = (remote.medAdcValue1)&0xff;
        remote.transmitBuffer[7] = (adcValue2 >> 8)&0xff;
        remote.transmitBuffer[8] = (adcValue2)&0xff;
        remote.transmitBuffer[9] = (remote.medAdcValue2 >> 8)&0xff;
        remote.transmitBuffer[10] =(remote.medAdcValue2)&0xff;
        remote.transmitBufferLen = 11;
    }
}

// non-block
void protocol_send_data(const uint8_t * buf, uint8_t len)
{
    static uint8_t temp_buffer[255];
    static uint8_t waitSendLen = 0, index = 0;
    // check send
    if (waitSendLen == 0){
        memset(temp_buffer, 0, len);
        waitSendLen = len;
        index = 0;
        if (len > 255)
            return;
        // copy buffer
        for (int i = 0; i < len; ++i) {
            temp_buffer[i] = buf[i];
        }
    }
    else{
        // send data
        // no loop
        // copy to transmitBuffer
        if (remote.transmitBufferLen == 0){
            memset(remote.transmitBuffer, 0, 32);
            remote.transmitBuffer[0] = 'D';
            if (waitSendLen >= 30){
                remote.transmitBuffer[1] = 30;
                for (int i = 0; i < 30; ++i) {
                    remote.transmitBuffer[i+2] = temp_buffer[i+index];
                }
                waitSendLen -= 30;
                index += 30;
            }
            else{
                remote.transmitBuffer[1] = waitSendLen;
                for (int i = 0; i < waitSendLen; ++i) {
                    remote.transmitBuffer[i+2] = temp_buffer[i+index];
                }
                index += waitSendLen;
                waitSendLen = 0;
            }
            // start send
            remote.transmitBufferLen = 1;
        }
    }
}

void protocol_analysis()
{
//    printf("oo\n");
    if (remote.protocolState == 0){
        remote.protocolState = 1;
        switch (remote.receiveBuffer[0]) {
            case 'D': // data
                start = HAL_GetTick();
                remote.protocolType = 'D';
                remote.receiveBufferLen = remote.receiveBuffer[1];
                break;
            case 'S': // selfCheck
                remote.protocolType = 'S';
                remote.id = remote.receiveBuffer[1];
                break;
            case 'C':// command
                remote.protocolType = 'C';
                remote.menuOperation = remote.receiveBuffer[2];
                remote.adcValue1 = (remote.receiveBuffer[3] << 8) | (remote.receiveBuffer[4]);
                remote.medAdcValue1 = (remote.receiveBuffer[5]<<8)|(remote.receiveBuffer[6]);
                remote.adcValue2 = (remote.receiveBuffer[7] << 8) | (remote.receiveBuffer[8]);
                remote.medAdcValue2 = (remote.receiveBuffer[9]<<8)|(remote.receiveBuffer[10]);
                break;
            default:
                remote.protocolState = 0;
                remote.state = PROTOCOL_ERROR;
                break;
        }
    }
}
